package org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.habilidad;

import org.javahispano.javacup.modelo.Comando;
import org.javahispano.javacup.modelo.ComandoGolpearBalon;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.entrenador.Sugerencia;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.Futbolista;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.FutbolistaBase;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.DespejeAlto;

/**
 * @author Joan Crosas
 *
 */
public class Despeje extends HabilidadConBalon {
	double potenciaDespeje;
	double anguloVerticalDespeje;

	/**
	 * @param futbolista
	 */
	public Despeje( Futbolista futbolista ) {
		super( futbolista );
		anguloVerticalDespeje = FutbolistaBase.ANGULO_VERTICAL_DESPEJE;
		potenciaDespeje = 1.0;
	}

	
	@Override
	public boolean ejecutar() {
		
		if( futbolista.getIteracionesParaRematar() == 0 && 
				futbolista.balonEncima( futbolista.getVisionPartido().getBalon() ) ) {
			
			
			double anguloBase = futbolista.getPosicion().angulo( FutbolistaBase.POSICION_PORTERIA_RIVAL );
			double desvioAngulo = 2d * Math.PI / FutbolistaBase.DIVISONES_ANGULO_DESPEJE;
			
			
			// NOTA: si el despeje se acerca a nuestra porteria lo descartamos
			DespejeAlto[] despejes = new DespejeAlto[FutbolistaBase.DIVISONES_ANGULO_DESPEJE];
			for( int i = 0; i < FutbolistaBase.DIVISONES_ANGULO_DESPEJE; i++ ) {
				despejes[i] = evaluarDespeje( anguloBase, potenciaDespeje, anguloVerticalDespeje );
				anguloBase = corregirAngulo( anguloBase + desvioAngulo );
			}
			
			// filtramos
			filtrar( despejes );
			
			// analizamos los pases
			DespejeAlto despejeAltoBueno = despejes[0];
			for( int i = 1; i < despejes.length; i++ ) {
				if( despejes[i].getPuntuacion() > despejeAltoBueno.getPuntuacion() ) {
					despejeAltoBueno = despejes[i];
				}
			}
			
			// preparamos los comandos
			Comando comando = new ComandoGolpearBalon(futbolista.getIndice(), despejeAltoBueno.getAngulo()*180/Math.PI, potenciaDespeje, anguloVerticalDespeje*180/Math.PI );
			futbolista.getVisionPartido().addComando( comando );
			
			if( despejeAltoBueno.getPosicionMinFutbolista() != null ) {
				Sugerencia sugerencia = new Sugerencia( Sugerencia.TipoSugerencia.RECIBIR_PASE );
				sugerencia.setFutbolista( despejeAltoBueno.getFutbolistaDestino() );
				sugerencia.setPosicionDestino( despejeAltoBueno.getPosicionMinFutbolista() );
				sugerencia.setTiempoValida( despejeAltoBueno.getPosicionMinFutbolista().getTiempo() + 2 );
				
				futbolista.getVisionPartido().addSugerencia( sugerencia );
			}
		}
		
		return true;
	}
	
	
	private void filtrar( DespejeAlto[] despejes ) {
		double filtro[] = { 1/4d, 2/4d, 3/4d, 1d , 3/4d, 2/4d, 1/4d };
		int indexCentroFiltro = (int) filtro.length / 2;
		double puntuacionesFiltradas[] = new double[despejes.length];
		for( int i = 0; i < despejes.length; i++ ) {
			double puntuacion = despejes[i].getPuntuacion() * filtro[indexCentroFiltro];
			for( int j = 1; j <= indexCentroFiltro; j++ ) {
				puntuacion += despejes[cursorCircular(i+j, despejes.length)].getPuntuacion() * filtro[indexCentroFiltro+j];
				puntuacion += despejes[cursorCircular(i-j, despejes.length)].getPuntuacion() * filtro[indexCentroFiltro-j];
			}
			puntuacionesFiltradas[i] = puntuacion;
		}
		for( int i = 0; i < despejes.length; i++ ) {
			despejes[i].setPuntuacion( puntuacionesFiltradas[i] );
		}
	}
	
	private int cursorCircular( int i, int max ) {
		return ( i + max ) % max;
	}
}
